package com.starlink.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.hutool.core.convert.Convert;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.CommonCreateOrderResponse;
import com.lop.open.api.sdk.domain.jdcloudprint.PullDataService.pullData.PrePrintDataInfo;
import com.starlink.client.jd.JdClient;
import com.starlink.client.jd.properties.JdProperties;
import com.starlink.client.jd.request.CreateOrderRequest;
import com.starlink.client.jd.request.PreCheckRequest;
import com.starlink.client.jd.request.PullDataRequest;
import com.starlink.client.jd.request.base.CommonCargoInfo;
import com.starlink.client.jd.request.base.CommonProductInfo;
import com.starlink.client.jd.request.base.Contact;
import com.starlink.client.jd.request.base.WayBillInfoRequest;
import com.starlink.client.jd.vo.PrintContentsVO;
import com.starlink.client.jd.vo.PrintPullDataVO;
import com.starlink.common.annotation.client.WeixinJsClient;
import com.starlink.common.annotation.client.weixin.UserPurchaseRes;
import com.starlink.common.annotation.client.weixin.WeixinJsCreateOrderReq;
import com.starlink.common.annotation.client.weixin.WeixinJsCreateOrderRes;
import com.starlink.common.domain.BaseEntity;
import com.starlink.common.enums.LogisticsOrderBusinessEnum;
import com.starlink.common.enums.OrderTypeEnum;
import com.starlink.common.exception.BusinessException;
import com.starlink.common.service.JdService;
import com.starlink.context.SessionContext;
import com.starlink.mapper.*;
import com.starlink.model.domain.*;
import com.starlink.model.request.*;
import com.starlink.model.request.mall.WechatPay;
import com.starlink.model.request.schoolbag.SchoolbagOrderSubmitRequest;
import com.starlink.model.util.AddressConvert;
import com.starlink.model.util.AdminAddressConvert;
import com.starlink.model.util.SchoolbagOrderReadRecordConvert;
import com.starlink.model.vo.*;
import com.starlink.service.*;
import com.starlink.utils.DateUtils;
import com.starlink.utils.OrderNumUtil;
import com.starlink.utils.OrderTimeOutUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.data.domain.Pageable;
import com.starlink.common.utils.AssertUtil;
import com.starlink.model.dtomapper.SchoolbagOrderDtoMapper;
import com.starlink.model.util.SchoolbagOrderConvert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import static com.starlink.common.enums.FreeEnum.FA_HUO_SHIPING;
import static com.starlink.utils.PageUtils.getOrderBy;
import static java.math.BigDecimal.ZERO;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author zhanghong
 */
@Slf4j
@Service
public class SchoolbagOrderServiceImpl extends ServiceImpl<SchoolbagOrderMapper, SchoolbagOrderDO> implements SchoolbagOrderService {
    @Autowired
    private SchoolbagOrderMapper schoolbagOrderMapper;
    @Autowired
    private WeixinJsClient weixinJsClient;
    @Autowired
    private AddressService addressService;
    @Autowired
    private SchoolbagMapper schoolbagMapper;
    @Autowired
    private SchoolbagService schoolbagService;
    @Autowired
    private SchoolbagSpecificationService schoolbagSpecificationService;
    @Autowired
    private SchoolbagGroupService schoolbagGroupService;
    @Autowired
    private SchoolbagGroupBagService schoolbagGroupBagService;
    @Autowired
    private SchoolbagOrderReadRecordService schoolbagOrderReadRecordService;
    @Autowired
    private MallBooksService mallBooksService;
    @Autowired
    private JdClient jdClient;
    @Autowired
    private MallLogisticsService logisticsService;
    @Autowired
    private JdProperties jdProperties;
    @Autowired
    private SchoolbagBooksStorageMapper schoolbagBooksStorageMapper;
    @Autowired
    private SchoolbagReadTestingService schoolbagReadTestingService;
    @Autowired
    private JdService jdService;
    @Autowired
    private AdminAddressMapper adminAddressMapper;

    @Override
    public SchoolbagOrderVO getByKey(long id) {
        SchoolbagOrderVO schoolbagOrderVO = SchoolbagOrderDtoMapper.INSTANCE.do2VO(getById(id));
        SchoolbagVO schoolbagVO = schoolbagService.getByKey(schoolbagOrderVO.getSchoolbagId());
        schoolbagOrderVO.setSchoolbag(schoolbagVO);
        AddressVO addressVo = addressService.getByKey(schoolbagOrderVO.getAddressId());
        schoolbagOrderVO.setReceiver(Optional.ofNullable(addressVo).map(AddressVO::getReceiver).orElse(null));
        schoolbagOrderVO.setProvince(Optional.ofNullable(addressVo).map(AddressVO::getProvince).orElse(null));
        schoolbagOrderVO.setCity(Optional.ofNullable(addressVo).map(AddressVO::getCity).orElse(null));
        schoolbagOrderVO.setArea(Optional.ofNullable(addressVo).map(AddressVO::getArea).orElse(null));
        schoolbagOrderVO.setDetail(Optional.ofNullable(addressVo).map(AddressVO::getDetail).orElse(null));
        // 查询用户订单计划
        List<SchoolbagOrderReadRecordDO> readRecordList = schoolbagOrderReadRecordService.lambdaQuery().eq(SchoolbagOrderReadRecordDO::getOrderId, schoolbagOrderVO.getId()).eq(SchoolbagOrderReadRecordDO::getSchoolbagId, schoolbagOrderVO.getSchoolbagId()).eq(SchoolbagOrderReadRecordDO::getSchoolbagSpecId, schoolbagOrderVO.getSchoolbagSpecId()).eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupId, schoolbagOrderVO.getSchoolbagGroupId()).list();
        List<SchoolbagOrderReadRecordVO> readRecordVOList = SchoolbagOrderReadRecordConvert.buildSchoolbagOrderReadRecordVoList(readRecordList);

        // 查询组号
        SchoolbagGroupDO one = schoolbagGroupService.lambdaQuery().eq(BaseEntity::getId, schoolbagOrderVO.getSchoolbagGroupId()).last("limit 1").one();
        if (one != null) {
            schoolbagOrderVO.setSchoolbagGroupCode(one.getGroupNo());

            for (SchoolbagOrderReadRecordVO item : readRecordVOList) {
                // 书包号
                SchoolbagGroupBagVO groupBagVO = schoolbagGroupBagService.getByKey(item.getSchoolbagGroupBagId());
                if (groupBagVO != null) {
                    item.setSchoolbagGroupBagCode(groupBagVO.getBagCode());
                }
                //
                item.setUserName(schoolbagOrderVO.getUserName());
                item.setMobile(schoolbagOrderVO.getMobile());
                // 书包书籍本数
                item.setSchoolbagBookNum(schoolbagVO.getSpecification());
                // 发货日期
                item.setDay(15);
                // 查询书籍列表信息
                List<MallBooksDO> bookImageList = mallBooksService.queryByGroupBagId(item.getSchoolbagGroupBagId());
                // 收件地址信息
                if (Objects.equals(item.getAddressId(), schoolbagOrderVO.getAddressId())) {
                    item.setReceiver(Optional.ofNullable(addressVo).map(AddressVO::getReceiver).orElse(null));
                    item.setProvince(Optional.ofNullable(addressVo).map(AddressVO::getProvince).orElse(null));
                    item.setCity(Optional.ofNullable(addressVo).map(AddressVO::getCity).orElse(null));
                    item.setArea(Optional.ofNullable(addressVo).map(AddressVO::getArea).orElse(null));
                    item.setDetail(Optional.ofNullable(addressVo).map(AddressVO::getDetail).orElse(null));
                    item.setMobile(Optional.ofNullable(addressVo).map(AddressVO::getMobile).orElse(null));
                } else if (item.getAddressId() != null) {
                    AddressVO itemAddressVo = addressService.getByKey(item.getAddressId());
                    item.setAddressId(itemAddressVo.getId());
                    item.setReceiver(Optional.ofNullable(itemAddressVo).map(AddressVO::getReceiver).orElse(null));
                    item.setProvince(Optional.ofNullable(itemAddressVo).map(AddressVO::getProvince).orElse(null));
                    item.setCity(Optional.ofNullable(itemAddressVo).map(AddressVO::getCity).orElse(null));
                    item.setArea(Optional.ofNullable(itemAddressVo).map(AddressVO::getArea).orElse(null));
                    item.setDetail(Optional.ofNullable(itemAddressVo).map(AddressVO::getDetail).orElse(null));
                    item.setMobile(Optional.ofNullable(itemAddressVo).map(AddressVO::getMobile).orElse(null));
                }
                item.setBookList(bookImageList);
                item.setIsTesting(schoolbagReadTestingService.lambdaQuery()
                        .eq(SchoolbagReadTestingDO::getOrderId, item.getOrderId())
                        .eq(SchoolbagReadTestingDO::getOrderReadId, item.getId()).exists());
            }
            schoolbagOrderVO.setReadRecordVOList(readRecordVOList);
        }

        return schoolbagOrderVO;
    }

    @Override
    public PageInfo<SchoolbagOrderVO> pageQuery(Pageable pageable, SchoolbagOrderRequest request) {
        if (Objects.equals(request.getOrderStatus(), 0)) {
            request.setOrderStatus(null);
        }
        PageHelper.startPage(request.getPageNum(), request.getPageSize(), getOrderBy(pageable.getSort())).setReasonable(true);
        List<SchoolbagOrderDO> list = schoolbagOrderMapper.listQuery(request);
        List<SchoolbagOrderVO> schoolbagOrderVOList = SchoolbagOrderConvert.buildSchoolbagOrderVoList(list);
        for (SchoolbagOrderVO schoolbagOrderVO : schoolbagOrderVOList) {
            schoolbagOrderVO.setSchoolbag(schoolbagService.getByKey(schoolbagOrderVO.getSchoolbagId()));
            // 查询组号
            SchoolbagGroupDO one = schoolbagGroupService.lambdaQuery().eq(BaseEntity::getId, schoolbagOrderVO.getSchoolbagGroupId()).last("limit 1").one();
            if (one != null) {
                schoolbagOrderVO.setSchoolbagGroupCode(one.getGroupNo());

                // 查询当前服务期数
                SchoolbagOrderReadRecordDO schoolbagOrderReadRecordDO = schoolbagOrderReadRecordService.lambdaQuery()
                        .eq(SchoolbagOrderReadRecordDO::getOrderId, schoolbagOrderVO.getId())
                        .eq(SchoolbagOrderReadRecordDO::getSchoolbagId, schoolbagOrderVO.getSchoolbagId())
                        .eq(SchoolbagOrderReadRecordDO::getSchoolbagSpecId, schoolbagOrderVO.getSchoolbagSpecId())
                        .eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupId, schoolbagOrderVO.getSchoolbagGroupId())
                        .notIn(SchoolbagOrderReadRecordDO::getServiceStatus, 4)
                        .orderByAsc(SchoolbagOrderReadRecordDO::getServiceSort)
                        .last("limit 1")
                        .one();
                if (schoolbagOrderReadRecordDO != null) {
                    schoolbagOrderVO.setSchoolbagCurrentNum(schoolbagOrderReadRecordDO.getServiceSort());
                    schoolbagOrderVO.setSchoolbagStatus(schoolbagOrderReadRecordDO.getServiceStatus());
                }
            }
        }
        return new PageInfo(schoolbagOrderVOList);
    }

    @Override
    public List<SchoolbagOrderVO> listQuery(SchoolbagOrderRequest request) {
        List<SchoolbagOrderDO> list = schoolbagOrderMapper.selectDOList(SchoolbagOrderDtoMapper.INSTANCE.request2DO(request));
        List<SchoolbagOrderVO> schoolbagOrderVOS = SchoolbagOrderConvert.buildSchoolbagOrderVoList(list);
        return schoolbagOrderVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(SchoolbagOrderRequest request) {
        save(SchoolbagOrderDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByKey(SchoolbagOrderRequest request) {
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        saveOrUpdate(SchoolbagOrderDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelOrder(SchoolbagOrderRequest request) {
        // 取消订单
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        saveOrUpdate(SchoolbagOrderDtoMapper.INSTANCE.request2DO(request));
        // todo 支付退款
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDOByIds(String ids) {
        schoolbagOrderMapper.deleteDOByIds(Convert.toStrArray(ids));
        return true;
    }

    @Override
    public UserPurchaseRes payment(SchoolbagOrderSubmitRequest request) {
        AssertUtil.assertNotNull(addressService.getByKey(request.getAddressId()), "收获地址不存在!");
        SchoolbagDO schoolbagDO = schoolbagMapper.selectDOById(request.getSchoolbagId());
        AssertUtil.assertNotNull(schoolbagDO, "书包不存在");
        AssertUtil.assertTrue(NumberUtil.equals(request.getPayMoney(), schoolbagDO.getPayPrice()), "支付金额和售卖金额不等");
        SchoolbagOrderDO order = null;

        if (request.getOrderId() != null) {
            order = schoolbagOrderMapper.selectDOById(request.getOrderId());
            AssertUtil.assertNotNull(order, "订单不存在");
        } else {
            // 写入订单
            order = new SchoolbagOrderDO();
            order.setOrderNo(OrderNumUtil.createUniqueOrderNum());
            order.setOrderAmount(request.getPayMoney());
            order.setOrderStatus(1);
            order.setUserId(SessionContext.getWechatUserId());
            order.setUserName(request.getUsername());
            order.setMobile(request.getMobile());
            order.setOpenId(request.getOpenId());
            order.setAddressId(request.getAddressId());
            order.setSchoolbagId(request.getSchoolbagId());
            order.setSchoolbagSpecId(request.getSchoolbagSpecId());
            order.setTimeout(OrderTimeOutUtil.getTimeOutTime());
            saveOrUpdate(order);
        }

        //创建微信预订单
        UserPurchaseRes vipRes = new UserPurchaseRes();
        vipRes.setOrderId(order.getId());
        vipRes.setOrderType(OrderTypeEnum.SCHOOLBAG.getType());

        WechatPay wechatPay = new WechatPay();
        wechatPay.setOrderId(String.valueOf(order.getId()));
        wechatPay.setOrderType(OrderTypeEnum.SCHOOLBAG.getType());
        String attach = JSONObject.toJSONString(wechatPay);
        WeixinJsCreateOrderReq req = new WeixinJsCreateOrderReq(order.getOrderNo(), order.getOrderAmount().doubleValue(), attach, request.getOpenId(), "书包订单");
        try {
            WeixinJsCreateOrderRes res = weixinJsClient.createOrder(req);
            weixinJsClient.buildPayRes(vipRes, res.getPrepay_id());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("微信下单失败!");
        }

        return vipRes;
    }

    // todo 加3次重试，并且在加定时任务进行兜底
    @Async
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @Override
    public Boolean joinGroup(Long schoolbagOrderId) {
        try {
            // 第一步：查询数据信息并进行校验
            SchoolbagOrderDO order = this.lambdaQuery()
                    .eq(BaseEntity::getId, schoolbagOrderId)
                    .last("limit 1")
                    .one();
            if (Objects.nonNull(order.getSchoolbagGroupId())) {
                log.info("订单({})已经参与过分组", schoolbagOrderId);
                return true;
            }
            AssertUtil.assertNotNull(order, "订单不存在");
            SchoolbagDO schoolbag = schoolbagService.lambdaQuery()
                    .eq(BaseEntity::getId, order.getSchoolbagId())
                    .last("limit 1")
                    .one();
            AssertUtil.assertNotNull(schoolbag, "订单所关联的书包类别不存在");
            SchoolbagSpecificationDO spec = schoolbagSpecificationService.lambdaQuery()
                    .eq(SchoolbagSpecificationDO::getSchoolbagId, order.getSchoolbagId())
                    .eq(BaseEntity::getId, order.getSchoolbagSpecId())
                    .last("limit 1")
                    .one();
            AssertUtil.assertNotNull(schoolbag, "订单所关联的书包类别-规格不存在");
            SchoolbagGroupDO group = schoolbagGroupService.lambdaQuery()
                    .eq(SchoolbagGroupDO::getCategoryId, schoolbag.getId())
                    .eq(SchoolbagGroupDO::getSpecId, spec.getId())
                    .lt(SchoolbagGroupDO::getBorrowNum, 12)
                    .orderByDesc(SchoolbagGroupDO::getBorrowNum)
                    .last("limit 1")
                    .one();
            AssertUtil.assertNotNull(group, "订单所关联的书包类别-规格-分组不存在");
            List<SchoolbagGroupBagDO> schoolbagGroupBagDOList = schoolbagGroupBagService.lambdaQuery()
                    .eq(SchoolbagGroupBagDO::getCategoryId, order.getSchoolbagId())
                    .eq(SchoolbagGroupBagDO::getSpecId, order.getSchoolbagSpecId())
                    .eq(SchoolbagGroupBagDO::getGroupId, group.getId())
                    .orderByAsc(SchoolbagGroupBagDO::getGroupIndex)
                    .list();
            AssertUtil.assertNotEmpty(schoolbagGroupBagDOList, "订单所关联的书包类别-规格-分组-书包不存在");
            AssertUtil.assertTrue(schoolbagGroupBagDOList.size() == 12, "订单所关联的书包类别-规格-分组-书包不完整(12)不存在");

            // 查询当前分组查询订单
            Integer groupIndex = 1;
            boolean existGroupOrder = this.lambdaQuery()
                    .eq(SchoolbagOrderDO::getSchoolbagGroupId, group.getId())
                    .exists();
            if (existGroupOrder) {
                // 查询当月应该发货的书包
                List<SchoolbagOrderReadRecordDO> currentMonthReadList = schoolbagOrderReadRecordService.lambdaQuery()
                        .eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupId, group.getId())
                        .eq(SchoolbagOrderReadRecordDO::getYear, DateUtil.thisYear())
                        .eq(SchoolbagOrderReadRecordDO::getMonth, DateUtil.thisMonth() + 1)
                        .orderByDesc(SchoolbagOrderReadRecordDO::getSchoolbagGroupIndex)
                        .list();
                AssertUtil.assertNotEmpty(currentMonthReadList, "存在书包订单，但是却不存在对应的阅读记录");
                SchoolbagOrderReadRecordDO readRecordDO = currentMonthReadList.get(0);
                if (DateUtils.isBeforeMidMonth(new Date())) {
                    // 当前处于15号之前：当月统一发货还没发出（当月发货）
                    if (readRecordDO.getSchoolbagGroupIndex() == 12) {
                        groupIndex = 1;// 已经是最大的index，则当前从1开始
                    } else {
                        groupIndex = readRecordDO.getSchoolbagGroupIndex() + 1;// 在当月还未发出的书包的最大index上往后排一个即可
                    }
                } else {
                    // 当前处于15号之后：当月统一发货已经发出（次月发货）
                    if (readRecordDO.getSchoolbagGroupIndex() == 12) {
                        groupIndex = 2;// 已经是最大的index，则当前从2开始
                    } else if (readRecordDO.getSchoolbagGroupIndex() == 11) {
                        groupIndex = 1;// 已经是倒数第二大的index，则当前从1开始
                    } else {
                        groupIndex = readRecordDO.getSchoolbagGroupIndex() + 2;
                    }
                }
            }

            List<SchoolbagGroupBagDO> schoolbagGroupBagDOS = rearrangeByGroupIndex(schoolbagGroupBagDOList, groupIndex);
            Integer serviceSort = 0;
            int year = DateUtil.thisYear();//第一次发货年份
            int month = DateUtils.isBeforeMidMonth(new Date()) ? DateUtil.thisMonth() + 1 : DateUtil.thisMonth() + 2;//第一次发货月份

            List<SchoolbagOrderReadRecordDO> readRecordDOS = Lists.newArrayList();
            for (SchoolbagGroupBagDO schoolbagGroupBagDO : schoolbagGroupBagDOS) {
                if (month - 12 > 0) {
                    // 特殊处理当前月份是11月，12月的情况，有可能month是大于12的情况，如果大于12则年份往前进1
                    year = year + 1;
                    month = month - 12;
                }

                SchoolbagOrderReadRecordDO readRecordDO = new SchoolbagOrderReadRecordDO();
                readRecordDO.setOrderId(order.getId());
                readRecordDO.setSchoolbagId(schoolbag.getId());
                readRecordDO.setSchoolbagSpecId(spec.getId());
                readRecordDO.setSchoolbagGroupId(group.getId());
                readRecordDO.setSchoolbagGroupBagId(schoolbagGroupBagDO.getId());
                readRecordDO.setYear(year);
                readRecordDO.setMonth(month);
                readRecordDO.setServiceSort(++serviceSort);
                readRecordDO.setSchoolbagGroupIndex(schoolbagGroupBagDO.getGroupIndex());
                readRecordDO.setServiceStatus(0);
                readRecordDO.setUserId(order.getUserId());
                readRecordDO.setAddressId(order.getAddressId());
                readRecordDOS.add(readRecordDO);
                month = month + 1;
            }
            schoolbagOrderReadRecordService.saveBatch(readRecordDOS);

            // 将编组信息更新到订单中
            order.setSchoolbagGroupId(group.getId());
            this.saveOrUpdate(order);
            // 更新分组出借数量
            group.setBorrowNum(Optional.ofNullable(group.getBorrowNum()).orElse(0) + 1);
            schoolbagGroupService.saveOrUpdate(group);
        } catch (BusinessException e) {
            log.error("订单:{} 编组失败 errorMessage = {}", schoolbagOrderId, e.getMessage(), e);
            throw new BusinessException(e.getErrorCode(), e.getMessage());
        } catch (Exception e) {
            log.error("订单:{} 编组异常 errorMessage = {}", schoolbagOrderId, e.getMessage(), e);
            throw e;
        }
        return true;
    }

    public static List<SchoolbagGroupBagDO> rearrangeByGroupIndex(List<SchoolbagGroupBagDO> schoolbagGroupBags, int startGroupIndex) {
        // 创建一个映射，以 groupIndex 为键，SchoolbagGroupBagDO 对象为值
        Map<Integer, SchoolbagGroupBagDO> indexToBagMap = schoolbagGroupBags.stream().collect(Collectors.toMap(SchoolbagGroupBagDO::getGroupIndex, bag -> bag));

        // 创建一个新的可变列表，初始化为12个null元素
        List<SchoolbagGroupBagDO> rearrangedBags = new ArrayList<>(Collections.nCopies(12, null));

        // 填充新列表，从startGroupIndex开始，按顺序添加到列表末尾，然后循环回1
        int currentIndex = startGroupIndex;
        for (int i = 0; i < rearrangedBags.size(); i++) {
            SchoolbagGroupBagDO bag = indexToBagMap.get(currentIndex);
            if (bag != null) {
                rearrangedBags.set(i, bag);
            }
            currentIndex = (currentIndex % 12) + 1; // 循环回到1
        }

        return rearrangedBags;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deliverySubmitJdOrder(SchoolbagOrderJdRequest request) {
        AssertUtil.assertNotNull(request.getSchoolbagOrderId(), "书包订单id不能为空");
        AssertUtil.assertNotNull(request.getSchoolbagReadRecordId(), "分期书包记录id不能为空");
        SchoolbagOrderDO order = schoolbagOrderMapper.selectDOById(request.getSchoolbagOrderId());
        AssertUtil.assertNotNull(order, "书包订单不存在");
        SchoolbagOrderReadRecordDO readRecord = schoolbagOrderReadRecordService.lambdaQuery()
                .eq(SchoolbagOrderReadRecordDO::getOrderId, order.getId())
                .eq(BaseEntity::getId, request.getSchoolbagReadRecordId())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(readRecord, "订单分期书包不存在");
        AssertUtil.assertTrue(Objects.equals(readRecord.getYear(), DateUtil.thisYear()) && Objects.equals(readRecord.getMonth(), DateUtil.thisMonth() + 1),
                String.format("暂不能发货，请按照发货计划发货，预期发货时间：%s-%s-15", readRecord.getYear(), readRecord.getMonth()));

        // 校验是否下过物流单了
        AssertUtil.assertStrEmpty(readRecord.getExpressDeliveryWaybillCode(), "已经发货并下单物流，请勿重复操作");

        //物流下单
        String logisticsOrderNum = LogisticsOrderBusinessEnum.XL.getCode() + OrderNumUtil.createJdUniqueOrderNum();
        CommonCreateOrderResponse response = jdService.creatJDOrder(16,
                "书包",
                AdminAddressConvert.buildContact(adminAddressMapper.selectOne()),
                AddressConvert.buildContact(addressService.lambdaQuery().eq(AddressDO::getId, order.getAddressId()).one()),
                new AtomicReference(new BigDecimal("0.1")),
                new AtomicReference(new BigDecimal("0.1")),
                logisticsOrderNum);

        //新增商家物流信息
        MallLogisticsRequest logisticsRequest = new MallLogisticsRequest();
        logisticsRequest.setOrderId(order.getId());
        logisticsRequest.setSubOrderId(readRecord.getId());
        logisticsRequest.setLogisticsNum(logisticsOrderNum);
        logisticsRequest.setAddressId(readRecord.getAddressId());
        logisticsRequest.setOrderType(5);
        logisticsRequest.setShippingDate(new Date());
        logisticsRequest.setShippingMethod("JD");
        logisticsRequest.setFreeType(FA_HUO_SHIPING.getType());
        logisticsRequest.setCreateTime(new Date());
        logisticsRequest.setCreateUser(SessionContext.getAdminUserId());
        logisticsRequest.setLogisticsOrderId(response.getOrderCode());
        logisticsRequest.setWaybillCode(response.getWaybillCode());
        logisticsRequest.setFreight(response.getFreightPre());
        logisticsService.add(logisticsRequest);

        // 更新阅读记录
        readRecord.setExpressDeliveryWaybillCode(response.getWaybillCode());
        readRecord.setExpressDeliveryTime(new Date());
        readRecord.setServiceStatus(1);//已发货
        return schoolbagOrderReadRecordService.saveOrUpdate(readRecord);
    }

    @Override
    public Boolean recoverySubmitJdOrder(SchoolbagOrderJdRequest request) {
        // 校验
        AssertUtil.assertNotNull(request.getSchoolbagOrderId(), "书包订单id不能为空");
        AssertUtil.assertNotNull(request.getSchoolbagReadRecordId(), "分期书包记录id不能为空");
        SchoolbagOrderDO order = schoolbagOrderMapper.selectDOById(request.getSchoolbagOrderId());
        AssertUtil.assertNotNull(order, "书包订单不存在");
        SchoolbagOrderReadRecordDO readRecord = schoolbagOrderReadRecordService.lambdaQuery()
                .eq(SchoolbagOrderReadRecordDO::getOrderId, order.getId())
                .eq(BaseEntity::getId, request.getSchoolbagReadRecordId())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(readRecord, "阅读记录不存在");
        AssertUtil.assertEqual(readRecord.getServiceStatus(), 2, "仅处于阅读中的书包可以联系物流回收");

        //新增商家物流信息
        String logisticsOrderNum = "XL" + OrderNumUtil.createJdUniqueOrderNum();
        MallLogisticsRequest logisticsRequest = new MallLogisticsRequest();
        logisticsRequest.setOrderId(order.getId());
        logisticsRequest.setSubOrderId(readRecord.getId());
        logisticsRequest.setLogisticsNum(logisticsOrderNum);
        logisticsRequest.setAddressId(readRecord.getAddressId());
        logisticsRequest.setOrderType(5);
        logisticsRequest.setShippingDate(new Date());
        logisticsRequest.setShippingMethod("JD");
        logisticsRequest.setFreeType(FA_HUO_SHIPING.getType());
//        //京东物流系统下单
//        //JD物流前置校验
//        jdPreCheck(readRecord.getAddressId());

        //物流下单
        AtomicReference<BigDecimal> weight = new AtomicReference<>(ZERO);
        AtomicReference<BigDecimal> volume = new AtomicReference<>(ZERO);
        AddressDO addressDO = addressService.lambdaQuery().eq(AddressDO::getId, readRecord.getAddressId()).one();
        CommonCreateOrderResponse commonCreateOrderResponse = creatJDOrder(16, "书包", addressDO, weight, volume, logisticsOrderNum);
        String waybillCode = commonCreateOrderResponse.getWaybillCode();
        String orderCode = commonCreateOrderResponse.getOrderCode();
        logisticsRequest.setCreateTime(new Date());
        logisticsRequest.setCreateUser(SessionContext.getAdminUserId());
        logisticsRequest.setLogisticsOrderId(orderCode);
        logisticsRequest.setWaybillCode(waybillCode);
        logisticsRequest.setFreight(commonCreateOrderResponse.getFreightPre());
        logisticsService.add(logisticsRequest);

        //
        readRecord.setExpressReturnWaybillCode(waybillCode);//回收物流运单号
        readRecord.setActualReturnTime(new Date());//实际归还时间
        readRecord.setServiceStatus(3);//商家已经下了回收物流单♻️，状态变更为
        schoolbagOrderReadRecordService.saveOrUpdate(readRecord);
        return true;
    }

    /**
     * 创建京东物流订单
     * @param num 件数
     * @param name
     * @param address
     * @param weight
     * @param volume
     * @param logisticsOrderNum
     * @return
     */
    private CommonCreateOrderResponse creatJDOrder(Integer num, String name,
                                                   AddressDO address,
                                                   AtomicReference<BigDecimal> weight,
                                                   AtomicReference<BigDecimal> volume,
                                                   String logisticsOrderNum) {
        CreateOrderRequest createOrderRequest = new CreateOrderRequest();
        //商家物流订单编号
        createOrderRequest.setOrderId(logisticsOrderNum);

        Contact sender = new Contact();
        sender.setName("张先生");
        sender.setMobile("18981732326");
        sender.setFullAddress("北京大兴区亦庄经济开发区京东总部2号楼B座");
        createOrderRequest.setSenderContact(sender);
        Contact receiver = new Contact();
        receiver.setName("王先生");
        receiver.setMobile("18981732326");
        receiver.setFullAddress("北京大兴区亦庄经济开发区京东总部2号楼B座");
//        receiver.setName(addressDO.getReceiver());
//        receiver.setMobile(addressDO.getMobile());
//        receiver.setFullAddress(addressDO.getProvince()+addressDO.getCity()+addressDO.getArea()+addressDO.getDetail());
        createOrderRequest.setReceiverContact(receiver);

        createOrderRequest.setOrderOrigin(1);
        createOrderRequest.setCustomerCode(jdProperties.getCustomerCode());

        CommonProductInfo productInfo = new CommonProductInfo();
        productInfo.setProductCode("ed-m-0001");
        createOrderRequest.setProductsReq(productInfo);

        createOrderRequest.setSettleType(3);

        List<CommonCargoInfo> cargoInfos = Lists.newArrayList();
        CommonCargoInfo cargoInfo = new CommonCargoInfo();
        cargoInfo.setName(name);
        cargoInfo.setQuantity(num);
//        cargoInfo.setWeight(weight.get());
//        cargoInfo.setVolume(volume.get());
        //TODO:重量体积不要为0
        cargoInfo.setWeight(new BigDecimal(1));
        cargoInfo.setVolume(new BigDecimal(0.1));
        cargoInfos.add(cargoInfo);
        createOrderRequest.setCargoes(cargoInfos);
        createOrderRequest.setRemark("测试单，勿接单");
        CommonCreateOrderResponse commonCreateOrderResponse = jdClient.create(createOrderRequest);
        return commonCreateOrderResponse;
    }

    private void jdPreCheck(Long addressId) {
        PreCheckRequest preCheckRequest = new PreCheckRequest();
        Contact sender = new Contact();
        sender.setFullAddress("河北省廊坊市广阳区万庄镇中心小学");
        preCheckRequest.setSenderContact(sender);

        Contact receiver = new Contact();
//        AddressDO addressDO = addressService.lambdaQuery().eq(AddressDO::getId, addressId).one();
//        receiver.setFullAddress(addressDO.getProvince()+addressDO.getCity()+addressDO.getArea()+addressDO.getDetail());
        receiver.setFullAddress("河北省廊坊市广阳区万庄镇中心小学");
        preCheckRequest.setReceiverContact(receiver);

        preCheckRequest.setOrderOrigin(1);
        preCheckRequest.setCustomerCode(jdProperties.getCustomerCode());

        CommonProductInfo productInfo = new CommonProductInfo();
        productInfo.setProductCode("ed-m-0001");
        preCheckRequest.setProductsReq(productInfo);
        jdClient.preCheck(preCheckRequest);
    }

    @Override
    public PrintPullDataVO getPrintData(SchoolbagOrderJdRequest request) {
        AssertUtil.assertNotNull(request.getSchoolbagOrderId(), "订单ID不能为空!");
        MallLogisticsDO logisticsDO = logisticsService.lambdaQuery().eq(MallLogisticsDO::getOrderId, request.getSchoolbagOrderId()).eq(MallLogisticsDO::getSubOrderId, request.getSchoolbagReadRecordId()).eq(MallLogisticsDO::getFreeType, FA_HUO_SHIPING.getType()).one();
        AssertUtil.assertNotNull(logisticsDO, "物流订单不存在!");
        String waybillCode = logisticsDO.getWaybillCode();
        PullDataRequest pullDataRequest = new PullDataRequest();
        pullDataRequest.setObjectId(OrderNumUtil.createUniqueOrderNum());
        WayBillInfoRequest wayBillInfoRequest = new WayBillInfoRequest();
        wayBillInfoRequest.setJdWayBillCode(waybillCode);
        List<WayBillInfoRequest> wayBillInfoRequests = Arrays.asList(wayBillInfoRequest);
        pullDataRequest.setWayBillInfos(wayBillInfoRequests);
        List<PrePrintDataInfo> dataInfos = jdClient.pullData(pullDataRequest);
        PrintPullDataVO printPullDataVO = new PrintPullDataVO();
        List<PrintContentsVO> printData = new ArrayList<>();
        dataInfos.forEach(dataInfo -> {
            String perPrintData = dataInfo.getPerPrintData();
            PrintContentsVO printContentsVO = new PrintContentsVO(jdProperties.getTempUrl(), perPrintData);
            printData.add(printContentsVO);
        });
        PrintPullDataVO pullDataVO = printPullDataVO.toPrintPullDataVO(OrderNumUtil.createPrintNum(), printData);
        return pullDataVO;
    }

    @Deprecated
    @Override
    public SchoolbagRecoveryVO getOrderInfoByRasId(SchoolbagRecoveryRequest request) {
        AssertUtil.assertNotNull(request.getBagCode(), "书包唯一编码不能为空");

        // 分组书包
        SchoolbagGroupBagDO schoolbagGroupBagDO = schoolbagGroupBagService.lambdaQuery()
                .eq(SchoolbagGroupBagDO::getBagCode, request.getBagCode())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(schoolbagGroupBagDO, "非法的书包唯一编码");
        // 分组
        SchoolbagGroupDO schoolbagGroupDO = schoolbagGroupService.lambdaQuery()
                .eq(BaseEntity::getId, schoolbagGroupBagDO.getGroupId())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(schoolbagGroupDO, "找不到对应的分组");
        // 规格
        SchoolbagSpecificationDO schoolbagSpecificationDO = schoolbagSpecificationService.lambdaQuery()
                .eq(BaseEntity::getId, schoolbagGroupDO.getSpecId())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(schoolbagSpecificationDO, "找不到对应的规格");
        // 书包
        SchoolbagDO schoolbagDO = schoolbagService.lambdaQuery().eq(BaseEntity::getId, schoolbagSpecificationDO.getSchoolbagId()).last("limit 1").one();
        AssertUtil.assertNotNull(schoolbagDO, "找不到对应的书包类型");
        // 阅读记录
        SchoolbagOrderReadRecordDO schoolbagOrderReadRecordDO = schoolbagOrderReadRecordService.lambdaQuery()
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagId, schoolbagDO.getId())
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagSpecId, schoolbagSpecificationDO.getId())
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupId, schoolbagGroupDO.getId())
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupBagId, schoolbagGroupBagDO.getId())
                .eq(SchoolbagOrderReadRecordDO::getYear, DateUtil.year(new Date()))
                .eq(SchoolbagOrderReadRecordDO::getMonth, DateUtil.month(new Date()) + 1)
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(schoolbagOrderReadRecordDO, "当前月份找不到对应的书包阅读记录");
        // 订单
        SchoolbagOrderVO schoolbagOrderVO = getByKey(schoolbagOrderReadRecordDO.getOrderId());
        AssertUtil.assertNotNull(schoolbagOrderVO, "找不到对应的书包订单记录");

        // 响应模型
        SchoolbagRecoveryVO recoveryVO = new SchoolbagRecoveryVO();
        // 1.书包信息
        recoveryVO.setOrderId(schoolbagOrderVO.getId());
        recoveryVO.setGroupCode(schoolbagGroupDO.getGroupNo());
        recoveryVO.setBookNum(schoolbagDO.getSpecification());
        recoveryVO.setSchoolbagCode(schoolbagGroupBagDO.getBagCode());
        recoveryVO.setSchoolbagRasCode(request.getBagCode());
        recoveryVO.setServiceNum(schoolbagOrderReadRecordDO.getServiceSort());
        // 2.书包阅读记录信息
        recoveryVO.setReadRecordId(schoolbagOrderReadRecordDO.getId());
        recoveryVO.setReadServiceStatus(schoolbagOrderReadRecordDO.getServiceStatus());
        // 3.订单信息
        recoveryVO.setSchoolbagName(schoolbagDO.getName());
        recoveryVO.setUsername(schoolbagOrderVO.getUserName());
        recoveryVO.setMobile(schoolbagOrderVO.getMobile());
        AddressVO addressVo = addressService.getByKey(schoolbagOrderVO.getAddressId());
        recoveryVO.setProvince(Optional.ofNullable(addressVo).map(AddressVO::getProvince).orElse(null));
        recoveryVO.setCity(Optional.ofNullable(addressVo).map(AddressVO::getCity).orElse(null));
        recoveryVO.setArea(Optional.ofNullable(addressVo).map(AddressVO::getArea).orElse(null));
        recoveryVO.setDetail(Optional.ofNullable(addressVo).map(AddressVO::getDetail).orElse(null));

        // 书籍码集合
        List<SchoolbagBooksStorageDO> schoolbagBooksStorageDOList = schoolbagBooksStorageMapper.listQueryByBagId(schoolbagGroupBagDO.getId());
        AssertUtil.assertNotEmpty(schoolbagBooksStorageDOList, "不存在对应的书包书籍码集合");
        recoveryVO.setBooksRasCode(schoolbagBooksStorageDOList.stream().map(SchoolbagBooksStorageDO::getRasCode).collect(Collectors.toList()));
        return recoveryVO;
    }

    @Override
    public SchoolbagRecoveryVO getWaitDeliveryOrderInfoByRasId(SchoolbagRecoveryRequest request) {
        AssertUtil.assertNotNull(request.getBagCode(), "书包唯一编码不能为空");
        SchoolbagGroupBagDO groupBag = schoolbagGroupBagService.lambdaQuery()
                .eq(SchoolbagGroupBagDO::getBagCode, request.getBagCode())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(groupBag, "分组书包不存在");

        SchoolbagOrderReadRecordDO readRecord = schoolbagOrderReadRecordService.lambdaQuery()
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupBagId, groupBag.getId())
                .eq(SchoolbagOrderReadRecordDO::getServiceStatus, 0)
                .eq(SchoolbagOrderReadRecordDO::getYear, DateUtil.year(new Date()))
                .eq(SchoolbagOrderReadRecordDO::getMonth, DateUtil.month(new Date()) + 1)
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(readRecord, "当前月份待发货阅读记录书包不存在");
        SchoolbagOrderVO order = getByKey(readRecord.getOrderId());
        AssertUtil.assertNotNull(order, "书包订单记录不存在");
        AssertUtil.assertNotNull(order.getAddressId(), "找不到对应的书包订单地址为空");
        AddressVO address = addressService.getByKey(order.getAddressId());
        AssertUtil.assertNotNull(address, "找不到对应的书包订单地址为空");
        SchoolbagGroupDO group = schoolbagGroupService.lambdaQuery()
                .eq(BaseEntity::getId, groupBag.getGroupId())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(group, "找不到对应的分组");
        SchoolbagSpecificationDO spec = schoolbagSpecificationService.lambdaQuery()
                .eq(BaseEntity::getId, group.getSpecId())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(spec, "找不到对应的规格");
        SchoolbagDO schoolbag = schoolbagService.lambdaQuery().eq(BaseEntity::getId, spec.getSchoolbagId()).last("limit 1").one();
        AssertUtil.assertNotNull(schoolbag, "找不到对应的书包类型");

        return SchoolbagRecoveryVO.builder()
                // 1.书包信息
                .orderId(order.getId())
                .groupCode(group.getGroupNo())
                .bookNum(schoolbag.getSpecification())
                .schoolbagCode(groupBag.getBagCode())
                .schoolbagRasCode(request.getBagCode())
                .serviceNum(readRecord.getServiceSort())
                // 2.书包阅读记录信息
                .readRecordId(readRecord.getId())
                .readServiceStatus(readRecord.getServiceStatus())
                // 3.订单信息
                .schoolbagName(schoolbag.getName())
                .username(order.getUserName())
                .mobile(order.getMobile())
                .province(Optional.ofNullable(address).map(AddressVO::getProvince).orElse(null))
                .city(Optional.ofNullable(address).map(AddressVO::getCity).orElse(null))
                .area(Optional.ofNullable(address).map(AddressVO::getArea).orElse(null))
                .detail(Optional.ofNullable(address).map(AddressVO::getDetail).orElse(null))
                .build();
    }

    @Override
    public SchoolbagRecoveryVO getWaitCollectOrderInfoByRasId(SchoolbagRecoveryRequest request) {
        AssertUtil.assertNotNull(request.getBagCode(), "书包唯一编码不能为空");
        SchoolbagGroupBagDO groupBag = schoolbagGroupBagService.lambdaQuery()
                .eq(SchoolbagGroupBagDO::getBagCode, request.getBagCode())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(groupBag, "分组书包不存在");

        SchoolbagOrderReadRecordDO readRecord = schoolbagOrderReadRecordService.lambdaQuery()
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupBagId, groupBag.getId())
                .eq(SchoolbagOrderReadRecordDO::getServiceStatus, 3)
                .eq(SchoolbagOrderReadRecordDO::getYear, DateUtil.year(new Date()))
                .eq(SchoolbagOrderReadRecordDO::getMonth, DateUtil.month(new Date()) + 1)
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(readRecord, "当前月份待收货阅读记录书包不存在");
        SchoolbagOrderVO order = getByKey(readRecord.getOrderId());
        AssertUtil.assertNotNull(order, "书包订单记录不存在");
        AssertUtil.assertNotNull(order.getAddressId(), "找不到对应的书包订单地址为空");
        SchoolbagGroupDO group = schoolbagGroupService.lambdaQuery()
                .eq(BaseEntity::getId, groupBag.getGroupId())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(group, "找不到对应的分组");
        SchoolbagSpecificationDO spec = schoolbagSpecificationService.lambdaQuery()
                .eq(BaseEntity::getId, group.getSpecId())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(spec, "找不到对应的规格");
        SchoolbagDO schoolbag = schoolbagService.lambdaQuery().eq(BaseEntity::getId, spec.getSchoolbagId()).last("limit 1").one();
        AssertUtil.assertNotNull(schoolbag, "找不到对应的书包类型");

        // 书籍码集合
        List<SchoolbagBooksStorageDO> bookRasCodeList = schoolbagBooksStorageMapper.listQueryByBagId(groupBag.getId());
        AssertUtil.assertNotEmpty(bookRasCodeList, "不存在对应的书包书籍码集合");

        return SchoolbagRecoveryVO.builder()
                // 1.书包信息
                .orderId(order.getId())
                .groupCode(group.getGroupNo())
                .bookNum(schoolbag.getSpecification())
                .schoolbagCode(groupBag.getBagCode())
                .schoolbagRasCode(request.getBagCode())
                .serviceNum(readRecord.getServiceSort())
                // 2.书包阅读记录信息
                .readRecordId(readRecord.getId())
                .readServiceStatus(readRecord.getServiceStatus())
                // 3.订单信息
                .schoolbagName(schoolbag.getName())
                .username(order.getUserName())
                .mobile(order.getMobile())
                // 4.书籍码集合
                .booksRasCode(bookRasCodeList.stream().map(SchoolbagBooksStorageDO::getRasCode).collect(Collectors.toList()))
                .build();
    }

    @Override
    @Transactional
    public SchoolbagRecoveryCheckVO recoveryCheck(SchoolbagRecoveryCheckRequest request) {
        AssertUtil.assertNotNull(request.getBagCode(), "书包唯一编码不能为空");
        SchoolbagGroupBagDO schoolbagGroupBagDO = schoolbagGroupBagService.lambdaQuery().eq(SchoolbagGroupBagDO::getBagCode, request.getBagCode()).last("limit 1").one();
        AssertUtil.assertNotNull(schoolbagGroupBagDO, "非法的书包唯一编码");

        SchoolbagGroupDO group = schoolbagGroupService.lambdaQuery().eq(BaseEntity::getId, schoolbagGroupBagDO.getGroupId()).last("limit 1").one();
        AssertUtil.assertNotNull(group, "找不到对应的分组");

        SchoolbagSpecificationDO spec = schoolbagSpecificationService.lambdaQuery().eq(BaseEntity::getId, group.getSpecId()).last("limit 1").one();
        AssertUtil.assertNotNull(spec, "找不到对应的规格");

        SchoolbagDO schoolbag = schoolbagService.lambdaQuery().eq(BaseEntity::getId, spec.getSchoolbagId()).last("limit 1").one();
        AssertUtil.assertNotNull(schoolbag, "找不到对应的书包类型");

        SchoolbagOrderReadRecordDO readRecord = schoolbagOrderReadRecordService.lambdaQuery()
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagId, schoolbag.getId())
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagSpecId, spec.getId())
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupId, group.getId())
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupBagId, schoolbagGroupBagDO.getId())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(readRecord, "找不到对应的书包订单记录");
        AssertUtil.assertTrue(readRecord.getServiceStatus() == 3, "当前书包状态非法不能进行此操作");

        SchoolbagOrderDO order = schoolbagOrderMapper.selectDOById(readRecord.getOrderId());
        AssertUtil.assertNotNull(order, "找不到对应的书包订单记录");

        readRecord.setServiceStatus(4);//4已收货(商家)
        readRecord.setServiceFinish(1);//当次服务是否完成 0否 1是
        readRecord.setCompanyConfirmTime(new Date());
        readRecord.setIsDeductionDeposit(request.getType());
        if (request.getType() != 0) {
            readRecord.setDeductionMoney(request.getDeductionDeposit());
            readRecord.setDeductionReason(request.getDeductionReason());
            readRecord.setDeductionImg(request.getDeductionImg());
            readRecord.setIsDeductionDeposit(0);
        }
        schoolbagOrderReadRecordService.saveOrUpdate(readRecord);

        // 查询当前回收的书包是否需要在15日发出(当前所属分组的其他订单是否需要这个书包)
        SchoolbagOrderReadRecordDO willSendReadRecord = schoolbagOrderReadRecordService.lambdaQuery()
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagId, schoolbag.getId())
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagSpecId, spec.getId())
                .eq(SchoolbagOrderReadRecordDO::getSchoolbagGroupId, group.getId())
                .eq(SchoolbagOrderReadRecordDO::getYear, DateUtil.year(new Date()))
                .eq(SchoolbagOrderReadRecordDO::getMonth, DateUtil.month(new Date()) + 1)
                .last("limit 1")
                .one();

        SchoolbagRecoveryCheckVO result = new SchoolbagRecoveryCheckVO();
        result.setSuccess(true);
        result.setWillSend(false);
        if (willSendReadRecord != null) {
            result.setWillSend(true);
        }
        return result;
    }
}
